iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
Software Development

由淺入深來探討Elasticsearch,從基礎語法到底層相關原理系列 第 22

【Day 22】由淺入深來探討Elasticsearch - Improve searching performance

  • 分享至 

  • xImage
  •  

我們今天進到查詢的最後一個部分
也就是在查詢時,要怎麼操作才能讓查詢
更加迅速以及比較不消耗資源呢?

可以分成幾個方面去探討:

  1. 系統優化
  2. 目標索引的處理
  3. 搜尋語句的優化

系統優化

  1. 硬體部分:
    • 如果search是屬於I/O bound的話,可以考慮增加filesystem cache的大小,並且因為搜尋可能需要再多分片上運行,使用SSD效果會更好
    • local storage會比remote storage表現更好
    • 如果是CPU-bound,使用更多與更快的cpu可以提升表現
  2. 軟體部分:
    • 在處理複雜的search時,需要消耗大量記憶體,可以安排coordinating node,獨立出記憶體來處理,避免被其他資源影響
    • 在yml等配置檔中,會建議JVM Heap size設置系統記憶體的50%左右

目標索引的處理

  1. 規劃好mapping的型態,避免使用消耗量大的查詢方式(expensive query)
    • 在沒有一些特殊關聯性下的狀況下不要使用nested或是join field
    • 避免schema on read,即使有也要根據慢慢確定的需求轉變成schema on write
      • script與runtime的成本太高
    • 如果原本只有單純的日期,現在需要多一個星期的需求
      • 可以再創建新索引,用reindex或是alias等方式處理
    • 一些numeric的欄位,如果不處理range等query。反而著重在term query,應該要將其轉換成keyword type更加合適,也會更快
    • 一些欄位可以用copy_to合併處理
      • 例如first name與last name合併成full name
      • 因為不會真的改變文檔的source,所以可以提升性能
{
  "mappings": {
    "properties": {
      "first_name": {
        "type": "text",
        "copy_to": "full_name"
      },
      "last_name": {
        "type": "text",
        "copy_to": "full_name"
      },
      "full_name": {
        "type": "text"
      }
    }
  }
}
  1. 對read-only的index,進行force-merge
    • 對於不再寫入的index,把內部的segment file進行merge,可以提升表現
    • 因為在合併的過程可以刪除不再需要或是不相關的segment file
  2. 對於常需要使用bucket aggregation的欄位,可以eager global ordinals設置為true
    • global ordinals存在JVM heap,並且作為field data cache的一部分
    • 通常是lazing loading,因為ES不會知道你會需要哪些欄位
  3. 可以針對hot index來設置index.store.preload,先載入資料到memory中
PUT /index_name
{
  "settings": {
    "index.store.preload": ["nvd", "dvd"] // nvd:norms dvd:doc values
  }
}
  1. replica的數量不一定多越好
    • 每個node中shard較少時搜尋表現更好,但是同時也增加資料毀損時的風險
    • 可以由下面公式來評估
max(max_failures, ceil(num_nodes / num_primaries) - 1)
// max_failures代表能接受多少node掛掉

控制結果部分

  • 因為filter不會需要計算相關分數,會更快。在可以的話能先用filter處理就不用query
  • 可以只返回特定類型的_source欄位
"_source": false
"_source": "created"
"_source": "field.key"
"_source": "field.*"
"_source": ["field.*", "other_fields"]
"_source": {"includes": "", "excludes": ""}
  • 如果不需要獲取全部筆數的話,可以設置返回size大小
  • 使用profile API來優化query。可以將每個query的階段拆開來分析,去看哪一些query消耗時間最久來進行優化
  • 在查詢時間相關時,可以避免用now來處理,因為沒有辦法形成cache,或是即使形成也很難再被其他query所用
    • 可以將時間透過四捨五入等進位方式,來將時間規範成較高的可用性
"date_field": { "gte": "now-1h", "lte": "now/"} 
//可以改成如下
"date_field": { "gte": "now-1h/m", "lte": "now/m"}
  • 但是如果無法接受這樣的切法,覺得我就是要now到1h之前的部分,一刻都不能少
    • 我們能將這段時間切割成3等份,讓大步份的資料能達到更高的cache hit rate

{
	"range": {
		"my_date": {
		"gte": "now-1h",
		"lte": "now-1h/m"
		}
	}
},
{
	"range": {
		"my_date": {
		"gte": "now-1h/m",
		"lte": "now/m"
		}
	}
},
{
	"range": {
		"my_date": {
		"gte": "now/m",
		"lte": "now"
		}
	}
}

以上就是有關查詢相關的性能優化~
希望大家在使用上能夠更加了解應該要怎麼處理自己的資料

明天的文章我們會再重新探討有關整個ES集群是怎麼被建立起來的
探討多節點要怎麼互相找到彼此,以及建立起一整個cluster

參考資料
turn for search speed:
https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-search-speed.html
查詢資料優化:
https://ithelp.ithome.com.tw/articles/10252695


上一篇
【Day 21】由淺入深來探討Elasticsearch - Aggregation (2)
下一篇
【Day 23】由淺入深來探討Elasticsearch - Discovery and cluster formation(1)
系列文
由淺入深來探討Elasticsearch,從基礎語法到底層相關原理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言